/*
 * ToolBar.java  0.4.0 / Oct 27, 2010
 *
 * Copyright (c) 2010 - 2011, cute4j.com and contributors.
 *
 * This software is licensed under the LGPL version 2.1 license.
 * A copy of this license is included in the file LICENSE-LGPL.txt.
 */
package com.cute4j.swing;

import com.cute4j.swing.graphics.Dimension;
import com.cute4j.swing.layouts.LayoutManager;
import com.cute4j.swing.properties.ToolbarProperties;

/**
 * ToolBar Component.
 *
 * @cute4j.native
 *    generate="header"
 *
 * @author Slobodan Vrkacevic
 * @version 0.4.0
 */
public class ToolBar extends Container
                     implements SwingConstants, ToolbarProperties {

// Static Initialization. ------------------------------------------------------

  static {
    _initialize();
  }

// Protected Fields. -----------------------------------------------------------

  private boolean floatable;
  private int orientation;
  private Dimension iconSize;
  private Dimension defaultIconSize;
  private boolean autoExclusive;

// Public Constructors. --------------------------------------------------------

  /**
   * Constructs new ToolBar object.
   */
  public ToolBar() {
    this(null, true);
  }

  /**
   * Constructs new ToolBar object.
   *
   * @param title the tool bar title
   */
  public ToolBar(String title) {
    this(title, true);
  }

  /**
   * Constructs new ToolBar object.
   *
   * @param title the tool bar title
   * @param autoExclusive <tt>true</tt> if auto exclusive
   */
  public ToolBar(String title, boolean autoExclusive) {
    super(null);
    floatable = true;
    if (title != null) {
      _setName(_delegate, title); // NOPMD
      name = title;
    }
    this.autoExclusive = autoExclusive;
  }

// Public Methods. -------------------------------------------------------------

  /**
   * Adds tool button item.
   *
   * @param toolButton the tool button
   *
   * @return the tool button argument
   */
  public ToolButton add(ToolButton toolButton) {
    addImpl(toolButton, null, -1);
    return toolButton;
  }

  /**
   * Adds tool button item.
   *
   * @param toolButton the tool button
   * @param index the tool button index
   *
   * @return the tool button argument
   */
  public ToolButton add(ToolButton toolButton, int index) {
    addImpl(toolButton, null, index);
    return toolButton;
  }

  /**
   * Adds toggle tool button item.
   *
   * @param toolButton the toggle tool button
   *
   * @return the toggle tool button argument
   */
  public ToggleToolButton add(ToggleToolButton toolButton) {
    return add(toolButton, -1);
  }

  /**
   * Adds toggle tool button item.
   *
   * @param toolButton the toggle tool button
   * @param index the toggle tool button index
   *
   * @return the toggle tool button argument
   */
  public ToggleToolButton add(ToggleToolButton toolButton, int index) { // NOPMD
    super.add(toolButton, index);
    if (autoExclusive) {
      if (index < 0) {
        index = componentCount - 1;
      }
      if (index > 0) {
        Component beforeComponent = components[index - 1];
        if (beforeComponent instanceof ToggleToolButton) { // NOPMD
          ToggleToolButton beforeButton = (ToggleToolButton)beforeComponent;
          SelectableGroup selectableGroup = beforeButton.getSelectableGroup();
          if (selectableGroup == null) {
            selectableGroup = new SelectableGroup();
            selectableGroup.add(beforeButton);
          }
          selectableGroup.add(toolButton);
        }
      }
    }
    return toolButton;
  }

  /**
   * Adds separator.
   *
   * @return separator
   */
  public Separator addSeparator() {
    Separator separator = new Separator();
    add(separator);
    return separator;
  }

  /**
   * Adds separator.
   *
   * @param index the separator index
   *
   * @return separator
   */
  public Separator addSeparator(int index) {
    Separator separator = new Separator();
    add(separator, index);
    return separator;
  }

  /**
   * Returns floatable property.
   *
   * @return floatable property
   */
  public boolean isFloatable() {
    return floatable;
  }

  /**
   * Sets floatable property.
   *
   * @param floatable the floatable property
   */
  public void setFloatable(boolean floatable) {
    final boolean oldFloatable = this.floatable;
    if (oldFloatable != floatable) {
      disposedCheck();
      _setFloatable(_delegate, floatable);
      this.floatable = floatable;
      firePropertyChange(PROPERTY_FLOATABLE, oldFloatable, floatable);
    }
  }

  /**
   * Returns orientation of the toolbar.
   *
   * @return orientation of the toolbar
   */
  public int getOrientation() {
    return orientation;
  }

  /**
   * Sets orientation.
   *
   * @param orientation the orientation
   */
  public void setOrientation(int orientation) {
    if ((orientation < HORIZONTAL) || (orientation > VERTICAL)) {
      throw new IllegalArgumentException("Invalid orientation");
    }
    disposedCheck();
    _setOrientation(_delegate, orientation);
  }

  /**
   * Returns default size of the tool bar icons.
   *
   * @return default size of the tool bar icons
   */
  public Dimension getDefaultIconSize() {
    return defaultIconSize;
  }

  /**
   * Sets default size of the tool bar icons.
   *
   * @param defaultIconSize the default size
   */
  public void setDefaultIconSize(Dimension defaultIconSize) {
    if (defaultIconSize == null) {
      throw new IllegalArgumentException("Null defaultIconSize");
    }
    disposedCheck();
    this.defaultIconSize = defaultIconSize;
    _setIconSize(_delegate, defaultIconSize.getWidth(),
                 defaultIconSize.getHeight());
  }

  /**
   * Sets default size of the tool bar icons.
   *
   * @param width the default width
   * @param height the height size
   */
  public void setDefaultIconSize(int width, int height) {
    setDefaultIconSize(new Dimension(width, height));
  }

// Overridden Methods. ---------------------------------------------------------

  /**
   * {@inheritDoc}
   */
  public void setLayout(LayoutManager layoutManager) {
    // empty method
  }

  /**
   * {@inheritDoc}
   */
  public void validate() {
    // empty method
  }

  /**
   * {@inheritDoc}
   */
  public void invalidate() {
    // empty method
  }

  /**
   * {@inheritDoc}
   */
  public void revalidate() {
    // empty method
  }

  /**
   * {@inheritDoc}
   */
  protected String paramString() {
    StringBuffer sb = new StringBuffer(80);
    sb.append(super.paramString());
    sb.append(",orientation=");
    if (orientation == HORIZONTAL) {
      sb.append("HORIZONTAL");
    } else {
      sb.append("VERTICAL");
    }
    if (floatable) {
      sb.append(",floatable");
    }
    return sb.toString();
  }

  void acquireChild(Component child) {
    if (defaultIconSize == null) {
      Icon icon = null;
      if (child instanceof ToolButton) {
        ToolButton toolButton = (ToolButton)child;
        icon = toolButton.getIcon();
      } else if (child instanceof ToggleToolButton) {
        ToggleToolButton toggleToolButton = (ToggleToolButton)child;
        icon = toggleToolButton.getIcon();
      }
      if (icon != null) {
        int iconWidth = icon.getIconWidth();
        int iconHeight = icon.getIconHeight();
        if (iconSize == null) {
          iconSize = new Dimension(iconWidth, iconHeight);
          _setIconSize(_delegate, iconWidth, iconHeight);
        } else {
          int oldIconWidth = iconSize.getWidth();
          int oldIconHeight = iconSize.getHeight();
          if (iconWidth < oldIconWidth) {
            iconWidth = oldIconWidth;
          }
          if (iconHeight < oldIconHeight) {
            iconHeight = oldIconHeight;
          }
          if ((iconWidth != oldIconWidth) || (iconHeight != oldIconHeight)) {
            iconSize = new Dimension(iconWidth, iconHeight);
            _setIconSize(_delegate, iconWidth, iconHeight);
          }
        }
      }
    }
    super.acquireChild(child);
  }

  void releaseChild(Component child) {
    if (child instanceof ToggleToolButton) {
      ToggleToolButton toggleToolButton = (ToggleToolButton)child;
      SelectableGroup selectableGroup = toggleToolButton.getSelectableGroup();
      if (selectableGroup != null) {
        selectableGroup.remove(toggleToolButton);
      }
    }
    super.releaseChild(child);
  }

// Native Callbacks. -----------------------------------------------------------

  void _orientationChanged(int orientation) {
    final int oldOrientation = this.orientation;
    if (oldOrientation != orientation) {
      this.orientation = orientation;
      firePropertyChange(PROPERTY_ORIENTATION, oldOrientation, orientation);
    }
  }

// Package-Private Native Methods. ---------------------------------------------

  native long _create();

  native void _setName(long delegate, String name);

  native void _insertChild(long delegate, long childDelegate, int index);

  native void _removeChild(long delegate, long childDelegate);

  native void _setFloatable(long delegate, boolean floatable);

  native void _setOrientation(long delegate, int orientation);

  native void _setIconSize(long delegate, int width, int height);

// Private Static Native Methods. ----------------------------------------------

  private static native void _initialize();

}
